home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDLFILE / GEMSTART.S < prev    next >
Encoding:
Text File  |  2001-02-09  |  24.8 KB  |  740 lines

  1. ******************************************************************************
  2. *
  3. * gemstart.s -startup code for the C runtime library, aesbind, vdibind
  4. *    
  5. *    IMPORTANT: SEE THE DESCRIPTION OF THE "STACK" VARIABLE, BELOW.
  6. *
  7. *    This is the startup code for any application running on the Atari ST.
  8. *    This includes gemlib, vdi, and the aes bindings.
  9. *
  10. *    Look carefully at the comments below; they will determine the nature
  11. *    of this startup code (stack size, AES & VDI usage, etc.).
  12. *
  13. *    This must be the first object file in a LINK command. When the
  14. *    operating system gives it control, our process has ALL of memory
  15. *    allocated to it, and our stack pointer is at the top.
  16. *    This code (conditionally) gives some of that memory back
  17. *    to the operating system, places its stack pointer at the top
  18. *    of the memory it still owns, sets up some global variables,
  19. *    and calls __main, the run-time library startup routine (which
  20. *    parses the command line into argc/argv, opens stdin and stdout,
  21. *    etc., before calling the programmer's _main).
  22. *
  23. *    This object file also includes __exit, which is the procedure the
  24. *    runtime library calls to exit back to the operating system.
  25. *    As a new feature with this release, the argument passed to __exit
  26. *    is NOT ignored; it is passed to the operating system using the Pterm
  27. *    function call, which returns it as the value of the Pexec() call
  28. *    which invoked this process.
  29. *
  30. ******************************************************************************
  31. *
  32. *    CONFIGUING THIS STARTUP FILE
  33. *
  34. *    There are several memory models which this startup file will
  35. *    assemble for, selected by the assembly variable STACK.
  36. *
  37. *    When your process gets control, it owns its basepage, its text
  38. *    (program) segment, its data segment, its bss segment (uninitialized
  39. *    data), and all the "free memory" from there to the top of the TPA.
  40. *    A process can choose to keep all that free memory for its stack
  41. *    (used by function calls and local variables) and heap (used by
  42. *    malloc()), or it can return some or all of that space to the
  43. *    operating system.
  44. *
  45. *    The memory between the top of your bss segment and your stack pointer
  46. *    is used both for a heap and for the stack.  The line between heap
  47. *    and stack is called the "break".  When malloc() uses up all the
  48. *    memory below the break, it calls _brk() (in this file) to move the 
  49. *    break up.  If the break gets too close to the stack, _brk() returns 
  50. *    an error code, and malloc() will return NULL because it couldn't
  51. *    satisfy the request.  If the stack actually overflows the break,
  52. *    _brk() prints an error message and exits, returning 1 to its parent.
  53. *
  54. *    If you are using the AES or VDI, you must return at least a little of
  55. *    the free memory to the operating system, because they need it.
  56. *    About 8K should be enough. The AES uses this memory for blt buffers,
  57. *    and the VDI uses it for virtual workstation data.
  58. *    Also, if your program uses the Pexec() call, you will need to return
  59. *    some space to make room for the child process.
  60. *
  61. *    It is usually a good idea to keep only as much memory as you will
  62. *    use, because some programs depend on processes returning some 
  63. *    memory to the operating system.
  64. *
  65. *************************************************************************
  66. *
  67. *    Here are the memory models you can set up with the STACK variable:
  68. *
  69. *    STACK
  70. *    value    Meaning
  71. *    ------    ---------------------------------------------------------
  72. *    -1    Keep all the memory for this process. Return NONE of it
  73. *        to the operating system.  This model gives you the most
  74. *        memory.
  75. *
  76. *        WARNING: IF YOU REQUEST ALL OF MEMORY (with STACK = -1),
  77. *        YOU MUST NOT USE THE AES, THE VDI, OR THE BIOS PEXEC() 
  78. *        FUNCTION. PEXEC WILL RETURN A CORRECT ERROR CODE (-39, 
  79. *        ENSMEM), BUT IT WILL ALSO BREAK THE MEMORY MANAGEMENT SYSTEM.
  80. *
  81. *     0    Return all but a minimal amount (MINSTACK) of the free
  82. *        space to the operating system.  This is a good idea if
  83. *        you know you won't be using malloc() much, or if you
  84. *        will be using Pexec() and your program doesn't need much
  85. *        stack space.  Remember, though, that some library functions,
  86. *        especially fopen(), use malloc() and will use your heap
  87. *        space.
  88. *
  89. *     1    Keep 1/4 of the free space.  This is a good model if
  90. *        you will be using malloc() a lot, but also want to use 
  91. *        Pexec() to spawn subprocesses.
  92. *
  93. *     2    Keep 2/4 (1/2) of the free space.  This is good if you
  94. *        use malloc() a lot, but don't want to be too much of a 
  95. *        memory hog.
  96. *
  97. *     3    Keep 3/4 of the free space.  This is a good choice for
  98. *        programs which use the AES or VDI, because it gives you plenty
  99. *        of room for using malloc(), but leaves enough for the
  100. *        AES and VDI to allocate their buffers, too.
  101. *
  102. *     4    This is a special value which means "Keep the number of
  103. *        bytes in the LONG global variable __STKSIZ."  You must declare
  104. *        a variable in your program called "_STKSIZ" and initialize
  105. *        it to the number of bytes you want for your stack and heap.
  106. *        If __STKSIZ is negative, it means "Keep all BUT the number
  107. *        of bytes in __STKSIZ."  As a safeguard, if __STKSIZ is
  108. *        undefined, you will get MINSTACK bytes of stack/heap.
  109. *
  110. *        An example using __STKSIZ this in C is:
  111. *
  112. *            /* outside all function blocks */
  113. *            unsigned long _STKSIZ = 32767;    /* 32K stack+heap */
  114. *        or
  115. *            unsigned long _STKSIZ = -8192;    /* keep all but 8K */
  116. *
  117. *        Note that in C, all variables get an underscore stuck on
  118. *        the front, so you just use one underscore in your program.
  119. *        Note also that it has to be all upper-case.
  120. *
  121. *    Any other POSITIVE value of STACK will be taken as the number of
  122. *    bytes you want to KEEP for your stack and heap.
  123. *
  124. *    Any other NEGATIVE value of STACK will be taken as the number of
  125. *    bytes you want to give back to the operating system.
  126. *
  127. *    Note that if you give back less than 512 bytes, you still shouldn't
  128. *    use Pexec(), and if you give back less than (about) 4K, you shouldn't
  129. *    use the AES or VDI.
  130. *
  131. *    In all cases, a minimum stack size is enforced.  This minimum is
  132. *    set by the variable MINSTACK in this assembly file.  This value
  133. *    should be at least 256 bytes, but should be more like 4K. If
  134. *    the stack size from the STACK model you choose or the _STKSIZ
  135. *    variable in your program is less than MINSTACK, you'll get
  136. *    MINSTACK bytes.  If there aren't MINSTACK bytes free past the end
  137. *    of your BSS, the program will abort with an error message.
  138. *
  139. *************************************************************************
  140. *
  141. * STACK variable summary:
  142. *    -1=keep all
  143. *     0=keep MINSTACK bytes
  144. *     1=keep 1/4 of free memory
  145. *     2=keep 2/4
  146. *     3=keep 3/4
  147. *     4=use _STKSIZ: keep (if >0) or give up (if <0) _STKSIZ bytes.
  148. *    other=keep that many bytes (positive) or give back that many (negative)
  149.  
  150. STACK=2            ; CHANGE THIS VARIABLE TO CHOOSE A MEMORY MODEL
  151. MINSTACK=4096        ; minimum stack+heap size.
  152. FUDGE=512        ; minimum space to leave ABOVE our stack
  153.  
  154. * BASEPAGE ADDRESSES:
  155. p_lowtpa=$0        ; Low TPA address (basepage address)
  156. p_hitpa=$4        ; High TPA address (and initial stack pointer)
  157. p_tbase=$8        ; ptr to Code segment start
  158. p_tlen=$c        ; Code segment length
  159. p_dbase=$10        ; ptr to Data segment start
  160. p_dlen=$14        ; Data segment length
  161. p_bbase=$18        ; ptr to Bss  segment start
  162. p_blen=$1c        ; Bss  segment length
  163. p_dta=$20        ; ptr to process's initial DTA
  164. p_parent=$24        ; ptr to process's parent's basepage
  165. p_reserved=$28        ; reserved pointer
  166. p_env=$2c        ; ptr to environment string for process
  167. p_cmdlin=$80        ; Command line image
  168.  
  169. *
  170. * CONTROL VARIABLES (used in stack computations)
  171. *
  172. * GOTSTACK: a boolean which is set TRUE if STACK in [-1..4], meaning "don't
  173. *        assemble the code keeping or returning STACK bytes."
  174. *
  175. * DOSHRINK: a boolean which is set FALSE if STACK is -1, meaning "don't
  176. *        shrink any memory back to the operating system."
  177. *
  178. gotstack    set    0    ; set to 1 if STACK in [-1..4]
  179. doshrink    set    1    ; default is 1; set to 0 if STACK = -1
  180.  
  181. * GEMDOS functions:
  182. cconws=$09        ; Cconws(string): write to console
  183. mshrink=$4a        ; Mshrink(newsize): shrink a block to a new size
  184. pterm=$4c        ; Pterm(code): exit, return code to parent
  185.  
  186. .globl    __start
  187. .globl    __main
  188. .globl    __exit
  189. .globl    _brk
  190. .globl    __break
  191. .globl    ___cpmrv
  192. .globl    __base
  193. .globl    __sovf
  194. .globl    _crystal
  195. .globl    _ctrl_cnts
  196.  
  197.  
  198.     .text
  199. *
  200. *  Must be first object file in link statement
  201. *
  202.  
  203. __start:
  204.     move.l    sp,a1        ; save our initial sp (used by ABORT)
  205.     move.l    4(sp),a0    ; a0 = basepage address
  206.     move.l    a0,__base    ; base = a0
  207.     move.l    p_bbase(a0),d0    ; d0 = bss seg start
  208.     add.l    p_blen(a0),d0    ; d0 += bss length  (d0 now = start of heap)
  209.     move.l    d0,__break    ; __break = first byte of heap
  210.  
  211. *************************************************************************
  212. *                                    *
  213. *    Compute stack size based on MINSTACK, p_hitpa(a0), STACK,    *
  214. *    and __STKSIZ, as appropriate.  Place the SP where you want    *
  215. *    your stack to be. Note that a0 == __base, d0 == __break        *
  216. *                                    *
  217. *    At most one of the STACK code fragments will be assembled.    *
  218. *    If none of them are, then `gotstack' will still be 0, and    *
  219. *    the final block, saving STACK bytes, is used. Finally, if    *
  220. *    STACK wasn't -1 (meaning don't shrink at all), DOSHRINK        *
  221. *    gets control.  See doshrink for more.                *
  222. *                                    *
  223. *************************************************************************
  224.  
  225. *************************************************************************
  226. *        STACK = -1: keep all of memory                *
  227. *************************************************************************
  228.  
  229.     .if    STACK = -1    ; if (STACK == -1)
  230. gotstack    set    1
  231. doshrink    set    0    ; this PREVENTS doshrink from assembling.
  232.     move.l    p_hitpa(a0),sp    ; place stack at top of tpa.
  233.     move.l    d0,d1        ; check against MINSTACK
  234.     add.l    #MINSTACK,d1    ; d1 = __break + MINSTACK;
  235.     cmp.l    sp,d1        ; if (sp < __break + MINSTACK)
  236.     bhi    abort        ;    goto abort;
  237.     .endif            ; (this falls through to the __main call)
  238.  
  239. *************************************************************************
  240. *        STACK = 0: keep only MINSTACK bytes            *
  241. *************************************************************************
  242.  
  243.     .if    STACK = 0
  244. gotstack    set    1
  245.     move.l    #MINSTACK,sp    ;    sp = __break+MINSTACK;
  246.     add.l    d0,sp
  247.     .endif            ; (this falls through to doshrink)
  248.  
  249. *************************************************************************
  250. *        STACK = 1: keep 1/4 of available memory            *
  251. *************************************************************************
  252.  
  253.     .if    STACK = 1    ; if (stack == 1) {    /* keep 1/2 */
  254. gotstack    set    1
  255.     move.l    p_hitpa(a0),d1    ;    d1 = p_hitpa;
  256.     sub.l    d0,d1        ;    d1 -= __break; /* d1 = free ram size */
  257.     lsr.l    #2,d1        ;    d1 /= 4;
  258.     add.l    d0,d1        ;    d1 += __break;     /* d1 = new sp */
  259.     move.l    d1,sp        ;     sp = d1;
  260.     .endif            ; } (this falls through to doshrink)
  261.  
  262. *************************************************************************
  263. *        STACK = 2: keep 2/4 of available memory            *
  264. *************************************************************************
  265.  
  266.     .if    STACK = 2    ; if (STACK == 2) {    /* keep 1/2 */
  267. gotstack    set    1
  268.     move.l    p_hitpa(a0),d1    ;    d1 = p_hitpa;
  269.     sub.l    d0,d1        ;    d1 -= __break; /* d1 = free ram size */
  270.     lsr.l    #1,d1        ;    d1 /= 2;
  271.     add.l    d0,d1        ;    d1 += __break; /* d1 = new sp */
  272.     move.l    d1,sp        ;     sp = d1;
  273.     .endif            ; this falls through to doshrink
  274.  
  275. *************************************************************************
  276. *        STACK = 3: keep 3/4 of available memory            *
  277. *************************************************************************
  278.  
  279.     .if    STACK = 3    ; if (STACK == 3) {    /* keep 3/4 */
  280. gotstack    set    1
  281.     move.l    p_hitpa(a0),d1    ;    d1 = p_hitpa;
  282.     sub.l    d0,d1        ;    d1 -= __break; /* d1 = free ram size */
  283.     lsr.l    #2,d1        ;    d1 /= 4;
  284.     move.l    d1,d2        ;    d2 = d1
  285.     add.l    d2,d1        ;    d1 += d2;
  286.     add.l    d2,d1        ;    d1 += d2; /* now d1 = 3*(d1/4) */
  287.     add.l    d0,d1        ;    d1 += __break;     /* d1 = new sp */
  288.     move.l    d1,sp        ;     sp = d1;
  289.     .endif            ; this falls through to doshrink
  290.  
  291. *************************************************************************
  292. *        STACK = 4: keep or give up __STKSIZ bytes of memory.    *
  293. *************************************************************************
  294.  
  295.     .if    STACK = 4    ; if (STACK == 4) {    /* keep __STKSIZ */
  296.     .globl __STKSIZ        ; global variable holding stack size
  297. gotstack    set    1
  298.     move.l    #__STKSIZ,a1    ; Check to see if __STKSIZ was undefined.
  299.     tst.l    a1        ; movea doesn't affect condition codes.
  300.     beq.s    keepmin        ; if it's zero, keep the minimum stack.
  301.     move.l    (a1),d1
  302.     bmi.s    giveback    ;    if (__STKSIZ < 0) goto giveback;
  303.     add.l    d0,d1        ;    d1 = __break+__STKSIZ; /* new sp */
  304.     bra.s    gotd1
  305.  
  306. keepmin:            ; __STKSIZ was undefined; keep minimum.
  307.     move.l    #MINSTACK,d1
  308.     add.l    d0,d1        ;    d1 = __break + MINSTACK;
  309.     bra.s    gotd1        ;    goto gotd1;
  310.  
  311. giveback:
  312.     add.l    p_hitpa(a0),d1    ;    d1 += hitpa;
  313.  
  314. gotd1:    move.l    d1,sp        ; gotd1: sp = d1;
  315.     .endif
  316.  
  317. *************************************************************************
  318. *        STACK is something else: keep (if STACK>0) or give    *
  319. *            back (if STACK<0) STACK bytes            *
  320. *************************************************************************
  321.  
  322.     .if    gotstack = 0    ; it's a constant stack value (+ or -)
  323.  
  324.     move.l    #STACK,d1    ;    /* if neg, give back STACK bytes */
  325.     bmi    giveback    ;    if (STACK < 0) goto giveback;
  326.     add.l    d0,d1        ;    d1 = STACK + __break; /* new sp */
  327.     bra    gotd1        ;    goto gotd1;
  328.  
  329. giveback:            ; giveback:
  330.     add.l    p_hitpa(a0),d1    ;    d1 += hitpa;    /* d1 = new sp */
  331. gotd1:                ; gotd1:
  332.     move.l    d1,sp        ;    sp = d1;
  333.     .endif
  334.  
  335. *************************************************************************
  336. *                                    *
  337. * DOSHRINK: take SP as a requested stack pointer. Place it        *
  338. * between (__break+MINSTACK) and (p_hitpa(a0)-FUDGE).  If we can't,    *
  339. * abort. Otherwise, we return the remaining memory back to the o.s.    *
  340. * The reason we always shrink by at least FUDGE bytes is to work around    *
  341. * a bug in the XBIOS Malloc() routine: when there are fewer than 512    *
  342. * bytes in the largest free block, attempting a Pexec() breaks the    *
  343. * memory management system.  Since all models except -1 permit Pexec()    *
  344. * calls, we have to make sure they don't break, even if the Pexec()    *
  345. * fails.  Thus, FUDGE must be at least 512.                *
  346. *                                    *
  347. *************************************************************************
  348. *
  349. * PSEUDOCODE:
  350. * doshrink(sp)
  351. * {
  352. *    /* if too low, bump it up */
  353. *    if (sp < (__break + MINSTACK))
  354. *        sp = (__break + MINSTACK);
  355. *
  356. *    /* if too high, bump it down */
  357. *    if (sp > (hitpa - FUDGE)) {
  358. *        sp = (hitpa - FUDGE);
  359. *
  360. *        /* if now too low, there's not enough memory */
  361. *        if (sp < (__break + MINSTACK))
  362. *            goto abort;
  363. *    }
  364. *    Mshrink(0,__base,(sp - __base));
  365. * }
  366. *
  367. *************************************************************************
  368.  
  369.     .if    doshrink <> 0    ; assemble this only if STACK != -1
  370.     move.l    d0,d1        ;     d1 = __break;
  371.     add.l    #MINSTACK,d1    ;     d1 += MINSTACK;
  372.     cmp.l    d1,sp        ;     if ((__break+MINSTACK) < sp)
  373.     bhi    minok        ;     goto minok;
  374.     move.l    d1,sp        ;     else sp = (__break+MINSTACK)
  375. minok:                ; minok:
  376.     move.l    p_hitpa(a0),d2    ;     d2 = hitpa;
  377.     sub.l    #FUDGE,d2    ;     d2 -= FUDGE;
  378.     cmp.l    d2,sp        ;     if ((hitpa - FUDGE) > sp)
  379.     bcs    maxok        ;    goto maxok;
  380. *                ;     else {
  381.     move.l    d2,sp        ;    sp = (hitpa - FUDGE);
  382.     cmp.l    d1,d2        ;     if ((__break+MINSTACK) > (hitpa-FUDGE))
  383.     bcs    abort        ;        goto abort;    /* BAD NEWS */
  384. *                ;     }
  385. maxok:
  386.  
  387. *************************************************************************
  388. * STACK LOCATION HAS BEEN DETERMINED. Return unused memory to the o.s.    *
  389. *************************************************************************
  390.  
  391.     move.l    sp,d1        ;     d1 = sp;
  392.     and.l    #-2,d1        ;     /* ensure d1 is even */
  393.     move.l    d1,sp        ;     sp = d1;
  394.     sub.l    a0,d1        ;     d1 -= __base; /* d1 == size to keep */
  395.  
  396.     move.l    d1,-(sp)    ; push the size to keep
  397.     move.l    a0,-(sp)    ; and start of this block (our basepage)
  398.     clr.w    -(sp)        ; and a junk word
  399.     move    #mshrink,-(sp)    ; and the function code
  400.     trap    #1        ; Mshrink(0,__base,(sp-base))
  401.     add.l    #12,sp        ; clean the stack after ourselves
  402.     .endif
  403.  
  404. *************************************************************************
  405. *                                    *
  406. * Finally, the stack is set up. Now call _main(cmdline, length).    *
  407. *                                    *
  408. *************************************************************************
  409.  
  410.     move.l    __base,a0    ; set up _main(cmdline,length)
  411.     lea.l    p_cmdlin(a0),a2    ; a2 now points to command line
  412.     move.b    (a2)+,d0    ; d0 = length; a2++;
  413.     ext.w    d0        ; extend byte count into d0.w
  414.     move.w    d0,-(a7)    ; push length
  415.     move.l    a2,-(a7)    ; Push commnd
  416.     clr.l    a6        ; Clear frame pointer
  417.     jsr    __main        ; call main routine    (rarely returns)
  418.     move.w    d0,-(sp)    ; push return value if __main returns
  419.     jsr    __exit        ; and call __exit.
  420.  
  421. ***********************************************************************
  422. *
  423. * _exit(code)    Terminate process, return code to the parent.
  424. *
  425. ***********************************************************************
  426.  
  427. __exit:
  428.     tst.l    (a7)+        ; drop return PC off the stack, leaving code
  429.     move.w    #pterm,-(a7)    ; push function number
  430.     trap    #1        ; and trap.
  431.  
  432. *
  433. * abort: used if the stack setup above fails. Restores the initial sp,
  434. * prints a message, and quits with the error ENSMEM.
  435. *
  436. abort:                ; print an abortive message and quit
  437.     move.l    a1,sp        ; restore initial sp
  438.     pea.l    abortmsg    ; push string address
  439.     move.w    #cconws,-(a7)    ; and function code
  440.     trap    #1        ; and trap to print message
  441.     addq.l    #6,a7        ; clean off stack
  442.     move.w    #-39,-(a7)    ; push error number -39: ENSMEM
  443.     jsr    __exit        ; and exit with it.
  444. *
  445. *
  446. _brk:        
  447.     cmp.l    __break,sp    ; compare current break with current stack
  448.     bcs    __sovf        ; actual stack overflow!
  449.     movea.l    4(sp),a0    ; get new break
  450.     move.l    a0,d0        ; compare with stack, including 256-byte
  451.     adda.l    #$100,a0    ; chicken factor
  452.     cmpa.l    a0,sp        ; if (sp < a0+256)
  453.     bcs    badbrk        ;     bad break;
  454.     move.l    d0,__break    ; OK break: save the break
  455.     clr.l    d0        ; Set OK return
  456.     rts            ; return
  457.  
  458. badbrk:
  459.     move.l    #-1,d0        ; Load return reg
  460.     rts            ; Return
  461. *
  462. * This ___BDOS code is broken: it comes from the DRI standard library's
  463. * need to do OS calls in its startup code.  See below for the fix, and
  464. * thanks to Robert Royar at the University of Louisville.
  465. *.globl    ___BDOS
  466. *___BDOS:
  467. *    link    a6,#0        ; link
  468. *    move.w    8(sp),d0    ; Load func code
  469. *    move.l    10(sp),d1    ; Load Paramter
  470. *    trap    #2        ; Enter BDOS
  471. *    cmpa.l    __break,sp    ; Check for stack ovf
  472. *    bcs    __sovf        ; overflow! print msg and abort
  473. *    unlk    a6        ; no error; return
  474. *    rts            ; Back to caller
  475.  
  476. ************************ BEGIN NEW, FIXED ___BDOS ***********************
  477.  
  478. .globl ___BDOS
  479. ___BDOS:
  480.     link    a6,#-4
  481.     move.w    $8(a6),d0
  482.     cmpi.w    #9,d0        ; test func code: print string?
  483.     beq    togem
  484.     cmpi.w    #2,d0        ; conout (2), conin (1), or term (0)?
  485.     bcs    togem
  486.     cmpi.w    #26,d0        ; setDTA?
  487.     bne    bdos        ; no - give to bdos
  488. togem:
  489.     move.l    $a(a6),(sp)
  490.     move.w    d0,-(sp)
  491.     bsr    xgemdos
  492.     addq.l    #2,sp
  493.     bra    out
  494.  
  495. bdos:
  496.     move.l    $a(a6),d1
  497. *                ; d0 already has function code
  498.     trap    #2
  499.     cmpa.l    __break,sp    ; check for overflow
  500.     bcs    __sovf        ; OVERFLOW! report the error and abort
  501. out:
  502.     unlk    a6
  503.     rts
  504.  
  505. xgemdos:
  506.     move.l    (sp)+,biosret
  507.     trap    #1
  508.     move.l    biosret,-(sp)
  509.     rts
  510.  
  511. .bss
  512. biosret:    ds.l    1
  513. .text
  514.  
  515. **************************** end of fixed ___BDOS **********************
  516.  
  517. *
  518. * stack overflow! This external is called by salloc in gemlib as well as above
  519. *
  520. __sovf:
  521.     move.l    #ovf,-(sp)    ; push message address
  522.     move.w    #cconws,-(sp)    ; push fn code
  523.     trap    #1        ; Issue message
  524.  
  525.     move.w    #1,-(a7)    ; push return code (1)
  526.     move.w    #pterm,d0    ; push function code (Pterm)
  527.     trap    #1        ; call Pterm(1) (never returns)
  528.  
  529. *
  530. *    Block Fill function:
  531. *
  532. *    blkfill(dest,char,cnt);
  533. *
  534. *    BYTE    ;dest;        ; -> area to be filled
  535. *    BYTE    char;        ; =  char to fill
  536. *    WORD    cnt;        ; =  # bytes to fill
  537. *
  538.     .globl    _blkfill
  539. _blkfill:
  540.     move.l    4(a7),a0    ; -> Output area
  541.     move.w    8(a7),d1    ; =  output char
  542.     move.w    10(a7),d0    ; =  output count
  543.     ext.l    d0        ; make it long
  544.     subq.l    #1,d0        ; decrement
  545.     ble    filldone    ; Done if le
  546. fillit:    move.b    d1,(a0)+    ; move a byte
  547.     dbra    d0,fillit    ; Continue
  548. filldone: clr.l    d0        ; always return 0
  549.     rts            ;
  550.  
  551. *
  552. *    Index function to find out if a particular character is in a string.
  553. *
  554.     .globl    _index
  555.     .globl    _strchr
  556. _index:
  557. _strchr:
  558.     move.l    4(a7),a0    ; a0 -> String
  559.     move.w    8(a7),d0    ; D0 = desired character
  560. xindex:    tst.b    (a0)        ; EOS?
  561.     bne    notend        ; No, continue to look
  562.     clr.l    d0        ; Not found
  563.     rts            ; Quit
  564. notend:    cmp.b    (a0)+,d0    ; check for character
  565.     bne    xindex        ;    
  566.     move.l    a0,d0        ; Found it
  567.     subq.l    #1,d0        ; set return pointer
  568.     rts
  569.  
  570. *
  571. *    For GEMAES calls from AESBIND.ARC or cryslib.o
  572. *
  573. _crystal:
  574.     move.l    4(a7),d1
  575.     move.w    #200,d0
  576.     trap    #2
  577.     rts
  578.  
  579. *
  580. *    Data area
  581. *
  582.     .data
  583.     .globl    ___pname    ; Program Name
  584.     .globl    ___tname    ; Terminal Name
  585.     .globl    ___lname    ; List device name
  586.     .globl    ___xeof        ; ^Z byte
  587. ovf:        .dc.b    'Stack Overflow',13,10,0    ; Overflow message
  588. ___pname:    .dc.b    'runtime',0    ; Program name
  589. ___tname:    .dc.b    'CON:',0    ; Console name
  590. ___lname:    .dc.b    'LST:',0    ; List device name
  591. ___xeof:    .dc.b    $1a        ; Control-Z
  592. abortmsg:    .dc.b    'Cannot initialize stack',13,10,0    ; abort message
  593.  
  594. **********************************************************************
  595. *
  596. * BSS AREA
  597. **********************************************************************
  598.     .bss
  599.     .even
  600. __base:        .ds.l    1    ; -> Base Page
  601. __break:    .ds.l    1    ; Break location
  602. ___cpmrv:    .ds.w    1    ; Last CP/M return val
  603.  
  604. *
  605. *    control array for vdibind
  606. *
  607.     .data
  608.         .even
  609. _ctrl_cnts:                 ;    Application Manager
  610.     .dc.b    0, 1, 0            ; func 010        
  611.         .dc.b    2, 1, 1            ; func 011        
  612.         .dc.b    2, 1, 1         ; func 012        
  613.     .dc.b    0, 1, 1            ; func 013        
  614.     .dc.b    2, 1, 1            ; func 014        
  615.     .dc.b    1, 1, 1            ; func 015        
  616.     .dc.b    0, 0, 0            ; func 016        
  617.     .dc.b    0, 0, 0            ; func 017        
  618.     .dc.b    0, 0, 0            ; func 008        
  619.     .dc.b    0, 1, 0            ; func 019        
  620. *                             Event Manager
  621.     .dc.b    0, 1, 0            ; func 020        
  622.     .dc.b    3, 5, 0            ; func 021        
  623.     .dc.b    5, 5, 0            ; func 022        
  624.     .dc.b    0, 1, 1            ; func 023        
  625.     .dc.b    2, 1, 0            ; func 024        
  626.     .dc.b    16, 7, 1         ; func 025        
  627.     .dc.b    2, 1, 0            ; func 026        
  628.     .dc.b    0, 0, 0            ; func 027        
  629.     .dc.b    0, 0, 0            ; func 028        
  630.     .dc.b    0, 0, 0            ; func 009        
  631. *                             Menu Manager
  632.     .dc.b    1, 1, 1            ; func 030        
  633.     .dc.b    2, 1, 1            ; func 031        
  634.     .dc.b    2, 1, 1            ; func 032        
  635.     .dc.b    2, 1, 1            ; func 033        
  636.     .dc.b    1, 1, 2            ; func 034        
  637.     .dc.b    1, 1, 1            ; func 005        
  638.     .dc.b    0, 0, 0            ; func 006        
  639.     .dc.b    0, 0, 0            ; func 007        
  640.     .dc.b    0, 0, 0            ; func 008        
  641.     .dc.b    0, 0, 0            ; func 009        
  642. *                             Object Manager
  643.     .dc.b    2, 1, 1            ; func 040        
  644.     .dc.b    1, 1, 1            ; func 041        
  645.       .dc.b    6, 1, 1            ; func 042        
  646.     .dc.b    4, 1, 1            ; func 043        
  647.     .dc.b    1, 3, 1            ; func 044        
  648.     .dc.b    2, 1, 1            ; func 045        
  649.     .dc.b    4, 2, 1            ; func 046        
  650.     .dc.b    8, 1, 1            ; func 047        
  651.     .dc.b    0, 0, 0            ; func 048        
  652.     .dc.b    0, 0, 0            ; func 049        
  653. *                             Form Manager
  654.     .dc.b    1, 1, 1            ; func 050        
  655.     .dc.b    9, 1, 1            ; func 051        
  656.     .dc.b    1, 1, 1            ; func 002        
  657.     .dc.b    1, 1, 0            ; func 003        
  658.     .dc.b    0, 5, 1            ; func 004        
  659.     .dc.b    0, 0, 0            ; func 005        
  660.     .dc.b    0, 0, 0            ; func 006        
  661.     .dc.b    0, 0, 0            ; func 007        
  662.     .dc.b    0, 0, 0            ; func 008        
  663.     .dc.b    0, 0, 0            ; func 009        
  664. *                             Dialog Manager
  665.     .dc.b    0, 0, 0            ; func 060        
  666.     .dc.b    0, 0, 0            ; func 061        
  667.     .dc.b    0, 0, 0            ; func 062        
  668.     .dc.b    0, 0, 0            ; func 003        
  669.     .dc.b    0, 0, 0            ; func 004        
  670.     .dc.b    0, 0, 0            ; func 005        
  671.     .dc.b    0, 0, 0            ; func 006        
  672.     .dc.b    0, 0, 0            ; func 007        
  673.     .dc.b    0, 0, 0            ; func 008        
  674.     .dc.b    0, 0, 0            ; func 009        
  675. *                            Graphics Manager
  676.     .dc.b    4, 3, 0            ; func 070        
  677.     .dc.b    8, 3, 0            ; func 071        
  678.     .dc.b    6, 1, 0            ; func 072        
  679.     .dc.b    8, 1, 0            ; func 073        
  680.     .dc.b    8, 1, 0            ; func 074        
  681.     .dc.b    4, 1, 1            ; func 075        
  682.     .dc.b    3, 1, 1            ; func 076        
  683.     .dc.b    0, 5, 0            ; func 077        
  684.     .dc.b    1, 1, 1            ; func 078        
  685.     .dc.b    0, 5, 0            ; func 009        
  686. *                            Scrap Manager
  687.     .dc.b    0, 1, 1            ; func 080        
  688.     .dc.b    0, 1, 1            ; func 081        
  689.     .dc.b    0, 0, 0            ; func 082        
  690.     .dc.b    0, 0, 0            ; func 083        
  691.     .dc.b    0, 0, 0            ; func 084        
  692.     .dc.b    0, 0, 0            ; func 005        
  693.     .dc.b    0, 0, 0            ; func 006        
  694.     .dc.b    0, 0, 0            ; func 007        
  695.     .dc.b    0, 0, 0            ; func 008        
  696.     .dc.b    0, 0, 0            ; func 009        
  697. *                            fseler Manager
  698.     .dc.b    0, 2, 2            ; func 090        
  699.     .dc.b    0, 0, 0            ; func 091        
  700.     .dc.b    0, 0, 0            ; func 092        
  701.     .dc.b    0, 0, 0            ; func 003        
  702.     .dc.b    0, 0, 0            ; func 004        
  703.     .dc.b    0, 0, 0            ; func 005        
  704.     .dc.b    0, 0, 0            ; func 006        
  705.     .dc.b    0, 0, 0            ; func 007        
  706.     .dc.b    0, 0, 0            ; func 008        
  707.     .dc.b    0, 0, 0         ; func 009        
  708. *                            Window Manager
  709.     .dc.b    5, 1, 0            ; func 100        
  710.     .dc.b    5, 1, 0            ; func 101        
  711.     .dc.b    1, 1, 0            ; func 102        
  712.     .dc.b    1, 1, 0            ; func 103        
  713.     .dc.b    2, 5, 0            ; func 104        
  714.     .dc.b    6, 1, 0            ; func 105        
  715.     .dc.b    2, 1, 0            ; func 106        
  716.     .dc.b    1, 1, 0            ; func 107        
  717.     .dc.b    6, 5, 0            ; func 108        
  718.     .dc.b    0, 0, 0         ; func 009        
  719. *                            Resource Manger
  720.     .dc.b    0, 1, 1            ; func 110        
  721.     .dc.b    0, 1, 0            ; func 111        
  722.     .dc.b    2, 1, 0            ; func 112        
  723.     .dc.b    2, 1, 1            ; func 113        
  724.     .dc.b    1, 1, 1            ; func 114        
  725.     .dc.b    0, 0, 0            ; func 115        
  726.     .dc.b    0, 0, 0            ; func 006
  727.     .dc.b    0, 0, 0            ; func 007
  728.     .dc.b    0, 0, 0            ; func 008
  729.     .dc.b    0, 0, 0            ; func 009
  730. *                            Shell Manager
  731.     .dc.b    0, 1, 2            ; func 120
  732.     .dc.b    3, 1, 2            ; func 121
  733.     .dc.b    1, 1, 1            ; func 122
  734.     .dc.b    1, 1, 1            ; func 123
  735.     .dc.b    0, 1, 1            ; func 124
  736.     .dc.b    0, 1, 2            ; func 125
  737.  
  738.     .end
  739.